#include "bsp_motor.h"

/**
 * @brief 初始化TB6612
 * 
 * @param pre 定时器预分频值，0~167
 * @param per 定时器自动重装载值，
 */
void TB6612_Init(uint16_t pre, uint16_t per)
{
    GPIO_InitTypeDef                 GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef          TIM_TimeBaseStructure;
    TIM_OCInitTypeDef                TIM_OCInitStructure;

    /* 使能时钟 */
    RCC_APB1PeriphClockCmd(RCC_PWMA_TIMER, ENABLE);//使能定时器3时钟
    RCC_AHB1PeriphClockCmd(RCC_PWMA, ENABLE);      //使能GPIO外设

    /* 初始化GPIO */
    GPIO_InitStructure.GPIO_Pin         = GPIO_PWMA | GPIO_PWMB;
    GPIO_InitStructure.GPIO_Mode        = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed       = GPIO_High_Speed;
    GPIO_Init(PORT_PWMA, &GPIO_InitStructure);

    /* GPIO复用引脚配置 */
    GPIO_PinAFConfig(PORT_PWMA, GPIO_PWMA_SOURCE, AF_PWMA);
    GPIO_PinAFConfig(PORT_PWMB, GPIO_PWMB_SOURCE, AF_PWMB);

    /* 初始化时基单元 */
    TIM_TimeBaseStructure.TIM_Period        = per - 1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    TIM_TimeBaseStructure.TIM_Prescaler     = pre - 1; //设置用来作为TIMx时钟频率除数的预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频
    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;  //TIM向上计数模式
    TIM_TimeBaseInit(BSP_PWMA_TIMER, &TIM_TimeBaseStructure);

    /* 初始化定时器通道PWM模式 */
    TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_High; //输出极性
    TIM_OC3Init(BSP_PWMA_TIMER, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

    TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_High; //输出极性
    TIM_OC4Init(BSP_PWMB_TIMER, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    
    TIM_OC3PreloadConfig(BSP_PWMA_TIMER, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
    TIM_OC4PreloadConfig(BSP_PWMB_TIMER, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器

    /* 开启定时器 */
    TIM_Cmd(BSP_PWMA_TIMER, ENABLE);
    TIM_Cmd(BSP_PWMB_TIMER, ENABLE);

    /* 初始化AIN、BIN的GPIO */
    AIN_GPIO_INIT();
    BIN_GPIO_INIT();
}

void AIN_GPIO_INIT(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AIN1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AIN2, ENABLE);

    GPIO_InitStructure.GPIO_Pin     = GPIO_AIN1 | GPIO_AIN2;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_DOWN;
    GPIO_Init(PORT_AIN2, &GPIO_InitStructure);
}

void BIN_GPIO_INIT(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_BIN1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_BIN2, ENABLE);

    GPIO_InitStructure.GPIO_Pin     = GPIO_BIN1 | GPIO_BIN2;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_DOWN;
    GPIO_Init(PORT_BIN2, &GPIO_InitStructure);
}

/**
 * @brief 电机控制
 * 
 * @param motor 电机A或电机B，取值：Motor_A，Motor_B
 * @param dir 旋转方向 1正转0反转
 * @param speed 旋转速度，范围（0 ~ per-1）
 */
void Motor_Control(uint8_t motor, uint8_t dir, uint32_t speed)
{
    if (motor == Motor_A)
    {
        if (dir == 1) {
            AIN1_OUT(0);
            AIN2_OUT(1);
        } else {
            AIN1_OUT(1);
            AIN2_OUT(0);
        }
        TIM_SetCompare3(BSP_PWMA_TIMER, speed);
    }
    else if (motor == Motor_B)
    {
        if (dir == 1) {
            BIN1_OUT(0);
            BIN2_OUT(1);
        } else {
            BIN1_OUT(1);
            BIN2_OUT(0);
        }
        TIM_SetCompare4(BSP_PWMB_TIMER, speed);
    }
}

